<template>
  <div class="schedule-container">
    <el-card>
      <div slot="header" class="header">
        <span>日程管理</span>
        <div>
          <el-button-group>
            <el-button :type="viewMode==='table'?'primary':'default'" icon="el-icon-menu" @click="viewMode='table'">表格</el-button>
            <el-button :type="viewMode==='card'?'primary':'default'" icon="el-icon-s-grid" @click="viewMode='card'">卡片</el-button>
            <el-button :type="viewMode==='calendar'?'primary':'default'" icon="el-icon-date" @click="viewMode='calendar'">日历</el-button>
          </el-button-group>
          <el-button type="primary" @click="handleAdd" style="margin-left:10px;">新增日程</el-button>
        </div>
      </div>

      <!-- 搜索栏 -->
      <div class="search-bar" v-if="viewMode!=='calendar'">
        <el-form :inline="true" :model="searchForm">
          <el-form-item>
            <el-input
              v-model="searchForm.title"
              placeholder="日程标题"
              clearable
              @keyup.enter.native="handleSearch"
            />
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="handleSearch">搜索</el-button>
          </el-form-item>
        </el-form>
      </div>

      <!-- 表格视图 -->
      <el-table
        v-if="viewMode==='table'"
        v-loading="loading"
        :data="scheduleList"
        border
        style="width: 100%"
      >
        <el-table-column prop="title" label="标题" min-width="150" />
        <el-table-column prop="content" label="内容" min-width="200" show-overflow-tooltip>
          <template slot-scope="scope">
            <span class="content-ellipsis" @click="showContent(scope.row.content)">
              {{ scope.row.content }}
            </span>
          </template>
        </el-table-column>
        <el-table-column prop="startTime" label="开始时间" width="180">
          <template slot-scope="scope">
            {{ scope.row.startTime | formatDateTime }}
          </template>
        </el-table-column>
        <el-table-column prop="endTime" label="结束时间" width="180">
          <template slot-scope="scope">
            <span :class="getTimeStatusClass(scope.row.endTime)">
              {{ scope.row.endTime | formatDateTime }}
            </span>
          </template>
        </el-table-column>
        <el-table-column prop="status" label="状态" width="100">
          <template slot-scope="scope">
            <el-tag
              :type="scope.row.status === 1 ? 'success' : 'info'"
              :class="scope.row.status === 0 ? 'status-unfinished' : ''"
              style="cursor:pointer"
              @click="toggleStatus(scope.row)"
            >
              {{ scope.row.status === 1 ? '已完成' : '未完成' }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="200" fixed="right">
          <template slot-scope="scope">
            <el-button
              type="text"
              size="small"
              @click="handleEdit(scope.row)"
            >编辑</el-button>
            <el-button
              type="text"
              size="small"
              class="delete-btn"
              @click="handleDelete(scope.row)"
            >删除</el-button>
          </template>
        </el-table-column>
      </el-table>

      <!-- 卡片视图 -->
      <el-row v-if="viewMode==='card'" :gutter="20">
        <el-col :xs="24" :sm="12" :md="8" :lg="6" v-for="item in scheduleList" :key="item.id">
          <el-card class="schedule-card" shadow="hover">
            <div class="card-header">
              <span class="card-title">{{ item.title }}</span>
              <el-tag :type="item.status===1?'success':'info'" size="mini">
                {{ item.status===1?'已完成':'未完成' }}
              </el-tag>
            </div>
            <div class="card-content">
              <div class="card-desc" @click="showContent(item.content)">
                {{ item.content.length>40 ? item.content.slice(0,40)+'...' : item.content }}
              </div>
              <div class="card-time">
                <span>开始：{{ item.startTime | formatDateTime }}</span>
                <span>结束：<span :class="getTimeStatusClass(item.endTime)">{{ item.endTime | formatDateTime }}</span></span>
              </div>
            </div>
            <div class="card-actions">
              <el-button type="text" size="small" @click="handleEdit(item)">编辑</el-button>
              <el-button type="text" size="small" class="delete-btn" @click="handleDelete(item)">删除</el-button>
              <el-button type="text" size="small" @click="toggleStatus(item)">
                {{ item.status===1?'标记未完成':'标记完成' }}
              </el-button>
            </div>
          </el-card>
        </el-col>
      </el-row>

      <!-- 日历视图 -->
      <el-calendar v-if="viewMode==='calendar'" :value="calendarDate" @input="onCalendarChange">
        <template slot="dateCell" slot-scope="{date}">
          <div :class="calendarCellClass(date)">
            <el-tooltip :content="getSchedulesByDate(date).length ? `共${getSchedulesByDate(date).length}个日程` : ''">
              <el-badge
                :value="getSchedulesByDate(date).length"
                :hidden="getSchedulesByDate(date).length===0"
                :type="getBadgeType(date)"
                class="calendar-badge"
              >
                <span :class="{'calendar-date-fade': getSchedulesByDate(date).length===0}">{{ date.getDate() }}</span>
              </el-badge>
            </el-tooltip>
            <ul>
              <li v-for="item in getSchedulesByDate(date)" :key="item.id">
                <el-tooltip placement="top" :content="getScheduleTooltip(item)">
                  <el-tag
                    :type="getScheduleTagType(item, date)"
                    size="mini"
                    @click.native="showScheduleDetail(item)"
                    class="calendar-schedule-tag"
                  >
                    <i v-if="item.priority==='高'" class="el-icon-star-on" style="color:#e6a23c;margin-right:2px;"></i>
                    {{ item.title }}
                  </el-tag>
                </el-tooltip>
              </li>
            </ul>
          </div>
        </template>
      </el-calendar>

      <!-- 分页 -->
      <div class="pagination-container" v-if="viewMode!=='calendar'">
        <el-pagination
          background
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
          :current-page="pageNo"
          :page-sizes="[10, 20, 50, 100]"
          :page-size="pageSize"
          layout="total, sizes, prev, pager, next, jumper"
          :total="total"
        />
      </div>
    </el-card>

    <!-- 新增/编辑对话框 -->
    <el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="500px">
      <el-form :model="form" :rules="rules" ref="form" label-width="100px">
        <el-form-item label="标题" prop="title">
          <el-input v-model="form.title" />
        </el-form-item>
        <el-form-item label="内容" prop="content">
          <el-input type="textarea" v-model="form.content" :rows="4" />
        </el-form-item>
        <el-form-item label="开始时间" prop="startTime">
          <el-date-picker
            v-model="form.startTime"
            type="datetime"
            placeholder="选择开始时间"
            value-format="yyyy-MM-dd HH:mm:ss"
          />
        </el-form-item>
        <el-form-item label="结束时间" prop="endTime">
          <el-date-picker
            v-model="form.endTime"
            type="datetime"
            placeholder="选择结束时间"
            value-format="yyyy-MM-dd HH:mm:ss"
          />
        </el-form-item>
        <el-form-item label="状态" prop="status">
          <el-select v-model="form.status" placeholder="请选择状态">
            <el-option label="未完成" :value="0" />
            <el-option label="已完成" :value="1" />
          </el-select>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="handleSubmit">确 定</el-button>
      </div>
    </el-dialog>

    <!-- 内容查看弹窗 -->
    <el-dialog title="日程内容" :visible.sync="contentDialogVisible" width="500px">
      <div style="white-space: pre-wrap;">{{ contentDialogText }}</div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="contentDialogVisible = false">关闭</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import {
  getScheduleList,
  addSchedule,
  updateSchedule,
  deleteSchedule
} from '@/api/schedule'

export default {
  name: 'Schedule',
  data() {
    return {
      // 视图切换
      viewMode: 'table', // table/card/calendar
      calendarDate: new Date(),
      // 搜索表单
      searchForm: {
        title: ''
      },
      // 分页参数
      pageNo: 1,
      pageSize: 10,
      total: 0,
      // 数据列表
      scheduleList: [],
      loading: false,
      // 对话框
      dialogVisible: false,
      dialogTitle: '',
      form: {
        id: null,
        title: '',
        content: '',
        startTime: '',
        endTime: '',
        status: 0
      },
      // 表单校验规则
      rules: {
        title: [
          { required: true, message: '请输入标题', trigger: 'blur' },
          { min: 2, max: 100, message: '长度在 2 到 100 个字符', trigger: 'blur' }
        ],
        content: [
          { required: true, message: '请输入内容', trigger: 'blur' }
        ],
        startTime: [
          { required: true, message: '请选择开始时间', trigger: 'change' }
        ],
        endTime: [
          { required: true, message: '请选择结束时间', trigger: 'change' }
        ],
        status: [
          { required: true, message: '请选择状态', trigger: 'change' }
        ]
      },
      contentDialogVisible: false,
      contentDialogText: ''
    }
  },
  created() {
    this.fetchData()
  },
  methods: {
    // 获取数据
    async fetchData() {
      this.loading = true
      try {
        const params = {
          pageNo: this.pageNo,
          pageSize: this.pageSize,
          title: this.searchForm.title
        }
        const res = await getScheduleList(params)
        if (res.data.code === 20000) {
          this.scheduleList = res.data.data.rows
          this.total = res.data.data.total
        } else {
          this.$message.error(res.data.message || '获取日程列表失败')
        }
      } catch (error) {
        console.error('获取日程列表失败:', error)
        this.$message.error('获取日程列表失败')
      }
      this.loading = false
    },
    // 日历切换
    onCalendarChange(val) {
      this.calendarDate = val
    },
    // 获取某天的日程
    getSchedulesByDate(date) {
      const y = date.getFullYear(), m = date.getMonth() + 1, d = date.getDate()
      const dayStr = `${y}-${String(m).padStart(2, '0')}-${String(d).padStart(2, '0')}`
      return this.scheduleList.filter(item => (item.startTime && item.startTime.startsWith(dayStr)) || (item.endTime && item.endTime.startsWith(dayStr)))
    },
    // 搜索
    handleSearch() {
      this.pageNo = 1
      this.fetchData()
    },
    // 新增
    handleAdd() {
      this.dialogTitle = '新增日程'
      this.form = {
        id: null,
        title: '',
        content: '',
        startTime: '',
        endTime: '',
        status: 0
      }
      this.dialogVisible = true
    },
    // 编辑
    handleEdit(row) {
      this.dialogTitle = '编辑日程'
      this.form = {
        ...row,
        startTime: row.startTime ? new Date(row.startTime) : '',
        endTime: row.endTime ? new Date(row.endTime) : ''
      }
      this.dialogVisible = true
    },
    // 删除
    async handleDelete(row) {
      this.$confirm('确认删除该日程吗？', '提示', {
        type: 'warning'
      })
        .then(async () => {
          try {
            const res = await deleteSchedule(row.id)
            if (res.data.code === 20000) {
              this.$message.success('删除成功')
              if (this.scheduleList.length === 1 && this.pageNo > 1) {
                this.pageNo--
              }
              this.fetchData()
            } else {
              this.$message.error(res.data.message || '删除失败')
            }
          } catch (error) {
            console.error('删除日程失败:', error)
            this.$message.error('删除失败')
          }
        })
        .catch(() => {})
    },
    // 提交表单
    handleSubmit() {
      this.$refs.form.validate(async valid => {
        if (valid) {
          try {
            let formData = { ...this.form }
            // 格式化时间为字符串
            if (formData.startTime instanceof Date) {
              formData.startTime = this.$options.filters.formatDateTime(formData.startTime)
            }
            if (formData.endTime instanceof Date) {
              formData.endTime = this.$options.filters.formatDateTime(formData.endTime)
            }
            // 只保留后端需要的字段
            let submitData = {
              id: formData.id,
              title: formData.title,
              content: formData.content,
              startTime: formData.startTime,
              endTime: formData.endTime,
              status: formData.status
            }
            console.log('提交数据', submitData)
            let res
            if (submitData.id) {
              res = await updateSchedule(submitData)
            } else {
              res = await addSchedule(submitData)
            }
            if (res.data.code === 20000) {
              this.$message.success(this.form.id ? '修改成功' : '新增成功')
              this.dialogVisible = false
              this.fetchData()
            } else {
              this.$message.error(res.data.message || (this.form.id ? '修改失败' : '新增失败'))
            }
          } catch (error) {
            console.error(this.form.id ? '修改日程失败:' : '新增日程失败:', error)
            this.$message.error(this.form.id ? '修改失败' : '新增失败')
          }
        }
      })
    },
    // 分页
    handleSizeChange(val) {
      this.pageSize = val
      this.fetchData()
    },
    handleCurrentChange(val) {
      this.pageNo = val
      this.fetchData()
    },
    getTimeStatusClass(endTime) {
      if (!endTime) return ''
      const now = new Date()
      const end = new Date(endTime)
      if (end < now) {
        return 'expired'
      }
      if (end - now < 24 * 60 * 60 * 1000) {
        return 'nearly-expired'
      }
      return ''
    },
    async toggleStatus(row) {
      const newStatus = row.status === 1 ? 0 : 1
      const res = await updateSchedule({ ...row, status: newStatus })
      if (res.data.code === 20000) {
        this.$message.success('状态切换成功')
        this.fetchData()
      } else {
        this.$message.error(res.data.message || '状态切换失败')
      }
    },
    showContent(content) {
      this.contentDialogText = content
      this.contentDialogVisible = true
    },
    // 日历格子样式
    calendarCellClass(date) {
      const now = new Date()
      const isToday = date.getFullYear()===now.getFullYear() && date.getMonth()===now.getMonth() && date.getDate()===now.getDate()
      const isWeekend = date.getDay()===0 || date.getDay()===6
      return {
        'calendar-cell': true,
        'calendar-today': isToday,
        'calendar-weekend': isWeekend
      }
    },
    // 日程标签类型
    getScheduleTagType(item, date) {
      if (item.status === 1) return 'success'
      // 快到期（24小时内）
      const end = new Date(item.endTime)
      const now = new Date(date)
      if (end - now < 24*60*60*1000 && end > now) return 'warning'
      return 'info'
    },
    // 日程标签悬浮详情
    getScheduleTooltip(item) {
      return `标题：${item.title}\n内容：${item.content}\n优先级：${item.priority||'普通'}\n时间：${item.startTime} ~ ${item.endTime}\n状态：${item.status===1?'已完成':'未完成'}`
    },
    // 日程详情弹窗
    showScheduleDetail(item) {
      this.contentDialogText = `标题：${item.title}\n内容：${item.content}\n开始：${item.startTime}\n结束：${item.endTime}\n状态：${item.status===1?'已完成':'未完成'}`
      this.contentDialogVisible = true
    },
    // 角标类型（颜色）
    getBadgeType(date) {
      const list = this.getSchedulesByDate(date)
      if (!list.length) return 'info'
      // 优先级：快到期>未完成>已完成
      if (list.some(item => this.getScheduleTagType(item, date)==='warning')) return 'warning'
      if (list.some(item => this.getScheduleTagType(item, date)==='info')) return 'primary'
      return 'success'
    }
  },
  filters: {
    formatDateTime(val) {
      if (!val) return ''
      const date = new Date(val)
      const year = date.getFullYear()
      const month = String(date.getMonth() + 1).padStart(2, '0')
      const day = String(date.getDate()).padStart(2, '0')
      const hour = String(date.getHours()).padStart(2, '0')
      const minute = String(date.getMinutes()).padStart(2, '0')
      const second = String(date.getSeconds()).padStart(2, '0')
      return `${year}-${month}-${day} ${hour}:${minute}:${second}`
    }
  },
  watch: {
    dialogVisible(val) {
      if (!val) {
        this.$nextTick(() => {
          if (this.$refs.form) this.$refs.form.resetFields()
        })
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.schedule-container {
  padding: 20px;

  .header {
    display: flex;
    justify-content: space-between;
    align-items: center;
  }

  .search-bar {
    margin-bottom: 20px;
  }

  .pagination-container {
    margin-top: 20px;
    text-align: right;
  }

  .delete-btn {
    color: #f56c6c;
  }

  .expired {
    color: #f56c6c;
    font-weight: bold;
  }
  .nearly-expired {
    color: #e6a23c;
    font-weight: bold;
  }

  .status-unfinished {
    border: 1px solid #f56c6c !important;
    color: #f56c6c !important;
    background: #fff0f0 !important;
  }

  .content-ellipsis {
    display: inline-block;
    max-width: 180px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    cursor: pointer;
    color: #409EFF;
  }

  .el-button {
    opacity: 0.7;
    transition: opacity 0.2s;
  }
  .el-button:hover {
    opacity: 1;
  }

  .calendar-cell {
    min-height: 80px;
    padding: 4px;
    border-radius: 6px;
    transition: background 0.2s;
    position: relative;
    &:hover {
      background: #f0f9ff;
      box-shadow: 0 2px 8px #e6f7ff;
      z-index: 1;
    }
  }
  .calendar-today {
    border: 2px solid #409EFF;
    background: #e6f7ff;
  }
  .calendar-weekend {
    background: #fafafa;
  }
  .calendar-badge {
    position: absolute;
    right: 6px;
    top: 2px;
    z-index: 2;
  }
  .calendar-schedule-tag {
    margin: 2px 0 2px 0;
    cursor: pointer;
    display: block;
    width: 100%;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .calendar-date-fade {
    color: #bbb;
    opacity: 0.7;
  }
}
</style> 
 
 
 